<?php

// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2020 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://demo.thinkadmin.top
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 代码仓库：https://gitee.com/zoujingli/ThinkAdmin
// | github 代码仓库：https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------

namespace app\common\queue;

use app\common\model\TaskLogs;
use library\service\ProcessService;
use think\Console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\facade\Log;

/**
 * 启动监听任务的主进程
 * Class ListenQueue
 * @package library\queue
 */
class ListenQueue extends Command
{
    /**
     * 当前进程服务
     * @var ProcessService
     */
    protected $process;

    /**
     * 配置指定信息
     */
    protected function configure()
    {
        $this->setName('listenQueue')->setDescription('Start task listening main process');
    }

    /**
     * 初始化进程服务
     * @param Input $input
     * @param Output $output
     */
    protected function initialize(Input $input, Output $output)
    {
        $this->process = ProcessService::instance();
    }

    /**
     * 执行进程守护监听
     * @param Input $input
     * @param Output $output
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    protected function execute(Input $input, Output $output)
    {
        set_time_limit(0);
        if ($this->process->iswin() && function_exists('cli_set_process_title')) {
            cli_set_process_title("ThinkAdmin {$this->process->version()} Queue Listen");
        }
        $output->writeln('============ LISTENING ============');
        while (true) {
            $map = [['status', 'eq', '1'], ['next_run_time', '<=', date('Y-m-d H:i:s')]];
            foreach (Db::name('Task')->where($map)->select() as $vo) {
                $start_at = date('Y-m-d H:i:s');
                $next_run_time = strtotime($vo['next_run_time']) + $vo['interval_time'];
                try {
                    Console::call($vo['command']);
                    $end_at = date('Y-m-d H:i:s');
                    TaskLogs::create([
                        'task_id' => $vo['id'],
                        'log' => 'success',
                        'status' => 1,
                        'executed_at' => date('Y-m-d H:i:s'),
                    ]);
                    Db::name('Task')->where(['id' => $vo['id']])->update([
                        'desc' => 'success',
                        'next_run_time' => date('Y-m-d H:i:s', $next_run_time),
                        'start_at' => $start_at,
                        'end_at' => $end_at,
                    ]);
                } catch (\Exception $e) {
                    TaskLogs::create([
                        'task_id' => $vo['id'],
                        'log' => $e->getMessage(),
                        'status' => 0,
                        'executed_at' => date('Y-m-d H:i:s'),
                    ]);
                    Db::name('Task')->where(['id' => $vo['id']])->update([
                        'desc' => $e->getMessage(),
                        'start_at' => $start_at,
                        'end_at' =>  date('Y-m-d H:i:s'),
                    ]);

                }
            }
            sleep(1);
        }
    }

}
